package com.queclink.ycm.common.utils;

import org.apache.commons.lang3.StringUtils;

/**
 * @author jim.li
 * @email jim.li@queclink.com
 * @date 2021-12-21 17:56:00
 */
public class HexUtils {

    public static void main(String[] args) throws Exception {

        String mmm = "安全帽检测NEW";
        String eeew = "192.168.1.13-0";
        String bbbb = "895B68513D5EC0684B6D4E0045005700";
        String ccccc = "3100390032002E003100360038002E0031002E00310033002D003000";
        String chatset = "UTF-16LE";//UTF-8//GBK//Unicode//UTF-16LE

        //编码
        String aaa = string2HexUTF16LE(mmm);
        System.out.println(aaa);

        //解码
        String wqqqq = hexUTF16LE2String(bbbb);
        System.out.println(wqqqq);

    }

    /**
     * 16进制转化为2进制字符串
     *
     * @param hexString
     * @return
     */
    public static String hexString2binaryString(String hexString) {
        if (hexString == null || hexString.length() % 2 != 0) {
            return null;
        }
        String bString = "", tmp;
        for (int i = 0; i < hexString.length(); i++) {
            tmp = "0000" + Integer.toBinaryString(Integer.parseInt(hexString.substring(i, i + 1), 16));
            bString += tmp.substring(tmp.length() - 4);
        }
        return bString;
    }

    /**
     * 16进制转10进制
     *
     * @param hex
     * @return
     */
    public static String hex2decimal(String hex) {
        byte[] bytes = new byte[hex.length() / 2];
        String result = "";
        for (int i = 0; i < bytes.length; i++) {
            int parseInt = Integer.parseInt(hex.substring(i * 2, (i + 1) * 2), 16);
            if (i == bytes.length - 1) {
                result = result + parseInt + "";
            } else {
                result = result + String.format("%2d", parseInt).replace(" ", "0");
            }
        }
        return result;
    }

    // Hex转byte
    public static byte[] hexStr2bytes(String hexStr) {
        if (StringUtils.isBlank(hexStr)) {
            return null;
        }
        if (hexStr.length() % 2 != 0) {//长度为单数
            hexStr = "0" + hexStr;//前面补0
        }
        char[] chars = hexStr.toCharArray();
        int len = chars.length / 2;
        byte[] bytes = new byte[len];
        for (int i = 0; i < len; i++) {
            int x = i * 2;
            bytes[i] = (byte) Integer.parseInt(String.valueOf(new char[]{chars[x], chars[x + 1]}), 16);
        }
        return bytes;
    }


    /**
     * @param b 字节数组
     * @return 16进制字符串
     * @throws
     * @Title:bytes2HexString
     * @Description:字节数组转16进制字符串
     */
    public static String bytes2HexString(byte[] b) {
        StringBuffer result = new StringBuffer();
        for (int i = 0; i < b.length; i++) {
            result.append(String.format("%02X", b[i]));
        }
        return result.toString();
    }

    /**
     * @param src 16进制字符串
     * @return 字节数组
     * @throws
     * @Title:hexString2Bytes
     * @Description:16进制字符串转字节数组
     */
    public static byte[] hexString2Bytes(String src) {
        int l = src.length() / 2;
        byte[] ret = new byte[l];
        for (int i = 0; i < l; i++) {
            ret[i] = Integer.valueOf(src.substring(i * 2, i * 2 + 2), 16).byteValue();
        }
        return ret;
    }


    /**
     * @param strPart 字符串
     * @return 16进制字符串
     * @throws
     * @Title:string2HexUTF8
     * @Description:字符UTF8串转16进制字符串
     */
    public static String string2HexUTF8(String strPart) {

        return string2HexString(strPart, "UTF-8");
    }

    /**
     * @param strPart 字符串
     * @return 16进制字符串
     * @throws
     * @Title:string2HexUTF8
     * @Description:字符UTF-16LE串转16进制字符串,此UTF-16LE等同于C#中的Unicode
     */
    public static String string2HexUTF16LE(String strPart) {

        return string2HexString(strPart, "UTF-16LE");
    }

    /**
     * @param strPart 字符串
     * @return 16进制字符串
     * @throws
     * @Title:string2HexUnicode
     * @Description:字符Unicode串转16进制字符串
     */
    public static String string2HexUnicode(String strPart) {

        return string2HexString(strPart, "Unicode");
    }

    /**
     * @param strPart 字符串
     * @return 16进制字符串
     * @throws
     * @Title:string2HexGBK
     * @Description:字符GBK串转16进制字符串
     */
    public static String string2HexGBK(String strPart) {

        return string2HexString(strPart, "GBK");
    }

    /**
     * @param strPart    字符串
     * @param tochartype hex目标编码
     * @return 16进制字符串
     * @throws
     * @Title:string2HexString
     * @Description:字符串转16进制字符串
     */
    public static String string2HexString(String strPart, String tochartype) {
        try {
            return bytes2HexString(strPart.getBytes(tochartype));
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * @param src 16进制字符串
     * @return 字节数组
     * @throws
     * @Title:hexUTF82String
     * @Description:16进制UTF-8字符串转字符串
     */
    public static String hexUTF82String(String src) {

        return hexString2String(src, "UTF-8", "UTF-8");
    }

    /**
     * @param src 16进制字符串
     * @return 字节数组
     * @throws
     * @Title:hexUTF16LE2String
     * @Description:16进制UTF-8字符串转字符串，,此UTF-16LE等同于C#中的Unicode
     */
    public static String hexUTF16LE2String(String src) {

        return hexString2String(src, "UTF-16LE", "UTF-8");
    }

    /**
     * @param src 16进制字符串
     * @return 字节数组
     * @throws
     * @Title:hexGBK2String
     * @Description:16进制GBK字符串转字符串
     */
    public static String hexGBK2String(String src) {

        return hexString2String(src, "GBK", "UTF-8");
    }

    /**
     * @param src 16进制字符串
     * @return 字节数组
     * @throws
     * @Title:hexUnicode2String
     * @Description:16进制Unicode字符串转字符串
     */
    public static String hexUnicode2String(String src) {
        return hexString2String(src, "Unicode", "UTF-8");
    }

    /**
     * @param src 16进制字符串
     * @return 字节数组
     * @throws
     * @Title:hexString2String
     * @Description:16进制字符串转字符串
     */
    public static String hexString2String(String src, String oldchartype, String chartype) {
        byte[] bts = hexString2Bytes(src);
        try {
            if (oldchartype.equals(chartype))
                return new String(bts, oldchartype);
            else
                return new String(new String(bts, oldchartype).getBytes(), chartype);
        } catch (Exception e) {

            return "";
        }
    }

    public static String intToHex(int n, int digit) {
        StringBuffer s = new StringBuffer();
        StringBuffer fill = new StringBuffer();
        String res;
        char[] b = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        while (n != 0) {
            s = s.append(b[n % 16]);
            n = n / 16;
        }
        for (int i = 0; i < digit - s.length(); i++) {
            fill.append("0");
        }
        res = s.append(fill.toString()).reverse().toString();
        return res;
    }


    public static String LongStrToHex(String str, int digit) {
        StringBuffer fill = new StringBuffer();
        String res;
        if (str.contains("-")) {
            res = "";
            return res;
        } else {
            String l = Long.toHexString(Long.valueOf(str));
            for (int i = 0; i < digit - l.length(); i++) {
                fill.append("0");
            }
            res = fill.append(l).toString();
            return res;
        }
    }


    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }

        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            stringBuilder.append(i + ":");
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv + ";");
        }
        return stringBuilder.toString();
    }

    public static String binaryToHex(String binary) {
        int decimal = Integer.parseInt(binary, 2);
        return intToHex(decimal, 2);
    }

    public static int binaryToInt(String binary) {
        if (binary == null) {
            System.out.println("can't input null ！");
        }
        if (binary.isEmpty()) {
            System.out.println("you input is Empty !");
        }
        int max = binary.length();
        String new_binary = "";
        if (max >= 2 && binary.startsWith("0")) {
            int position = 0;
            for (int i = 0; i < binary.length(); i++) {
                char a = binary.charAt(i);
                if (a != '0') {
                    position = i;
                    break;
                }
            }
            if (position == 0) {
                new_binary = binary.substring(max - 1, max);
            } else {
                new_binary = binary.substring(position, max);
            }
        } else {
            new_binary = binary;
        }
        int new_width = new_binary.length();

        long result = 0;
        if (new_width < 32) {
            for (int i = new_width; i > 0; i--) {
                char c = new_binary.charAt(i - 1);
                int algorism = c - '0';
                result += Math.pow(2, new_width - i) * algorism;
            }
        } else if (new_width == 32) {
            for (int i = new_width; i > 1; i--) {
                char c = new_binary.charAt(i - 1);
                int algorism = c - '0';
                result += Math.pow(2, new_width - i) * algorism;
            }
            result += -2147483648;
        }
        int a = new Long(result).intValue();
        return a;
    }

    public static int lenToHex(Integer len) {
        if (len > 127) {
            String s = "1";
            s += decimal2binary(len, 15);
            return binaryToInt(s);
        } else {
            String s = "0";
            s += decimal2binary(len, 7);
            return binaryToInt(s);
        }
    }

    public static int frameLenToHex(Integer len) {
        String s = decimal2binary(len, 16);
        return binaryToInt(s);

    }


    public static String decimal2binary(int decNum, int digit) {
        String binStr = "";
        for (int i = digit - 1; i >= 0; i--) {
            binStr += (decNum >> i) & 1;
        }
        return binStr;
    }

    public static String versionToHex(String version) {
        StringBuffer sb = new StringBuffer();
        String[] targetVer = version.split("(?<=\\G..)");
        for (String s : targetVer) {
            Integer i = Integer.valueOf(s);
            sb.append(intToHex(i, 2));
        }
        return sb.toString();
    }


}
